home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-11 | 32.9 KB | 1,301 lines | [TEXT/MPS ] |
- /*
- File: Selection.cpp
-
- Contains: Selection Classes Implementation
-
- Written by: Dave Stafford
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
- */
-
- // -- DrawEditor Includes --
-
- #ifndef _COMPILERDEFS_
- #include "CompDefs.h"
- #endif
-
- #ifndef _DRAWEDTORUTILS_
- #include "DrawEditorUtils.h"
- #endif
-
- #ifndef _SELECTION_
- #include "Selection.h"
- #endif
-
- #ifndef _LINK_
- #include "Link.h"
- #endif
-
- #ifndef _DRAWEDITOR_
- #include "DrawEditor.h"
- #endif
-
- #ifndef _DRAWEDITORUTILS_
- #include "DrawEditorUtils.h"
- #endif
-
- #ifndef _SHAPECOMMANDS_
- #include "ShapeCommands.h"
- #endif
-
- #ifndef _SHAPES_
- #include "Shapes.h"
- #endif
-
- // -- OpenDoc Includes --
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _TEMPITER_
- #include <TempIter.h>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODFrameFacetIterator_xh
- #include "FrFaItr.xh"
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _ODDEBUG_
- #include <ODDebug.h>
- #endif
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef _STDTYPIO_
- #include "StdTypIO.h"
- #endif
-
- #ifndef _ODUTILS_
- #include "ODUtils.h"
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef _FOCUSLIB_
- #include "FocusLib.h"
- #endif
-
- #ifndef _ORDCOLL_
- #include "OrdColl.h"
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- // -- Toolbox Includes --
-
- #ifndef mathRoutinesIncludes
- #include <math routines.h>
- #endif
-
- #ifndef __MEMORY__
- #include <memory.h>
- #endif
-
- #ifndef __DRAG__
- #include <Drag.h>
- #endif
-
- // **************************** Need to improve Handling of Failure **********************
-
- //=============================================================================
- // CSelection
- //=============================================================================
-
-
- //-----------------------------------------------------------------------------
- // CSelection::CSelection
- //-----------------------------------------------------------------------------
-
- CSelection::CSelection(DrawEditor* editor, ODBoolean allowPublish, ODBoolean allowSubscribe)
- {
- fDrawEditor = editor;
-
- fEmbeddingShapeCount = 0L;
- fFrozenCount = 0L;
-
- fUpdateShape = kODNULL;
- fSelectionRectangle = gGlobals->fZeroRect;
-
- fAllowPublish = allowPublish;
- fAllowSubscribe = allowSubscribe;
-
- fShapeList = new COrderedList;
- fPublishLinks = new COrderedList;
- fSubscribeLinks = new COrderedList;
-
- fPartialSubscribeCount = 0;
-
- fSelectionContent = new CSelectionContent(editor, fShapeList, fPublishLinks, fSubscribeLinks, this);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::~CSelection
- //-----------------------------------------------------------------------------
-
- CSelection::~CSelection()
- {
- Environment* ev = somGetGlobalEnvironment();
-
- ODSafeReleaseObject(fUpdateShape);
- fUpdateShape = kODNULL;
-
- delete fShapeList;
- delete fPublishLinks;
- delete fSubscribeLinks;
-
- delete fSelectionContent;
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::IsCompletelyUnfrozen
- //-----------------------------------------------------------------------------
-
- ODBoolean CSelection::IsCompletelyUnfrozen() const
- {
- return fShapeList->Count() != 0 && fFrozenCount != fShapeList->Count();
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::SetFrozen
- //
- // Make all shapes currently in this collection frozen.
- //-----------------------------------------------------------------------------
-
- void CSelection::SetFrozen(Environment* ev, ODBoolean state)
- {
- COrdListIterator i(fShapeList);
- for (CShape* shape = (CShape*) i.First(); i.IsNotComplete(); shape = (CShape*) i.Next())
- {
- if (shape->SetFrozen(state))
- {
- state ? fFrozenCount++ : fFrozenCount--;
- }
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::ContainsFrozen
- //-----------------------------------------------------------------------------
-
- ODBoolean CSelection::ContainsFrozen() const
- {
- return fFrozenCount != 0;
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::IsEmpty
- //-----------------------------------------------------------------------------
-
- ODBoolean CSelection::IsEmpty() const
- {
- return fShapeList->Count() == 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::Add
- //-----------------------------------------------------------------------------
-
- void CSelection::Add(Environment* ev, CShape* shape)
- {
- fShapeList->AddLast(shape);
-
- if (shape->GetShapeType() == kEmbeddingShape)
- fEmbeddingShapeCount++;
- if (shape->IsFrozen())
- fFrozenCount++;
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::Remove
- //-----------------------------------------------------------------------------
-
- void CSelection::Remove(Environment* ev, CShape* shape)
- {
- fShapeList->Remove(shape);
-
- if (shape->GetShapeType() == kEmbeddingShape)
- fEmbeddingShapeCount--;
- if (shape->IsFrozen())
- fFrozenCount--;
- }
-
- #pragma segment Main
- CEmbeddingShape* CSelection::IsOneEmbeddedShape(Environment* ev)
- {
- // this access may be able to go away if we implement
- // CDrawContent::HandleExternalize
-
- return fSelectionContent->IsOneEmbeddedShape(ev);
- }
-
-
- #pragma segment Main
- COrderedList* CSelection::GetShapeList()
- {
- return fShapeList;
- }
-
- #pragma segment Main
- CDrawContent* CSelection::GetSelectionContent()
- {
- return fSelectionContent;
- }
-
-
- #pragma segment Main
- COrderedList* CSelection::GetPublishLinks()
- {
- return fPublishLinks;
- }
-
-
- #pragma segment Main
- COrderedList* CSelection::GetSubscribeLinks()
- {
- return fSubscribeLinks;
- }
-
- #pragma segment Main
- ODULong CSelection::Count()
- {
- return fShapeList->Count();
- }
-
-
- #pragma segment Main
- DrawEditor* CSelection::GetDrawEditor()
- {
- return fDrawEditor;
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::GetUpdateShape
- //-----------------------------------------------------------------------------
-
- ODShape* CSelection::GetUpdateShape()
- {
- return fUpdateShape;
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::Dragging
- //-----------------------------------------------------------------------------
-
- void CSelection::Dragging(Environment* ev, ODBoolean dragging )
- {
- COrdListIterator ite(this->GetShapeList());
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- shape->Dragging(ev, dragging);
- }
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::GetSelectionRectangle
- //-----------------------------------------------------------------------------
-
- void CSelection::GetSelectionRectangle(ODRect* rectangle)
- {
- *rectangle = fSelectionRectangle;
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::ExternalizeSingleEmbeddedFrame
- //-----------------------------------------------------------------------------
-
- void CSelection::ExternalizeSingleEmbeddedFrame(Environment* ev,
- ODStorageUnit* storage,
- CCloneInfo* info,
- ODFrame* embeddedFrame)
- {
- fSelectionContent->ExternalizeSingleEmbeddedFrame(ev, storage,
- info, embeddedFrame);
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::HandleInternalizeContent
- //-----------------------------------------------------------------------------
-
- void CSelection::HandleInternalizeContent(Environment* ev,
- ODStorageUnit* storageUnit,
- CCloneInfo* info)
- {
- fSelectionContent->HandleInternalizeContent(ev, storageUnit, info);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::HandleTranslateContent
- //-----------------------------------------------------------------------------
-
- void CSelection::HandleTranslateContent(Environment* ev,
- ODStorageUnit* storageUnit,
- CCloneInfo* info,
- ODBoolean embedOrMerge)
- {
- fSelectionContent->HandleTranslateContent(ev, storageUnit, info, embedOrMerge);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::SetInLimbo
- //-----------------------------------------------------------------------------
-
- void CSelection::SetInLimbo(Environment* ev, ODBoolean isInLimbo )
- {
- COrdListIterator ite(fShapeList);
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- shape->SetInLimbo(ev, isInLimbo);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::SelectedContentUpdated
- //-----------------------------------------------------------------------------
-
- void CSelection::SelectedContentUpdated(Environment* ev, ODBoolean doClear)
- {
-
- COrderedList tempList;
-
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- COrderedList* pLinks = kODNULL;
- CSubscribeLink* sLink = shape->GetSubscribeLink();
-
- if (sLink)
- pLinks = sLink->GetPublishLinks();
- else
- pLinks = shape->GetPublishLinks();
-
- if (pLinks->Count() != 0)
- {
- COrdListIterator linkIter(pLinks);
- for (CPublishLink* pLink = (CPublishLink*)linkIter.First(); linkIter.IsNotComplete(); pLink = (CPublishLink*)linkIter.Next())
- {
- if (!pLink->WasRemoved())
- tempList.AddLast(pLink);
- }
- }
- }
-
- // In a clear operation, we need to now actually clear the selection so that the updates to links and frame
- // represent the changed content
- if (doClear)
- {
- // Remove Subscribers.
- while (fSubscribeLinks->Count() != 0)
- {
- CSubscribeLink *sLink = (CSubscribeLink*)fSubscribeLinks->RemoveFirst();
-
- // Remove the subscribe link and its shapes from the part and the selection.
- // Setting the subscribe link as responsible for removing AND replacing shapes
- // makes undo/redo of clear or cut safe and easy.
-
- sLink->RemoveFromPart(ev, kODTrue);
- }
-
- // Remove the remaining shapes.
- CShape *shape;
- while (fShapeList->Count() != 0)
- {
- shape = (CShape*)fShapeList->First();
- Remove(ev, shape); // Remove from Selection list
- shape->SelectShape(ev, kODFalse); // (MH) Necessary to keep links working properly.
- fDrawEditor->RemoveShape(ev, shape); // Remove from shape list
- }
- }
-
- // Call ContentChanged on all shape links
- ODUpdateID id = fDrawEditor->GetSession(ev)->UniqueUpdateID(ev);
-
- while (tempList.Count() != 0)
- {
- CPublishLink* pLink = (CPublishLink *)tempList.RemoveFirst();
-
- // tempList may contain duplicates, but update each link only once
- if (pLink->GetUpdateID() != id)
- pLink->ContentUpdated(ev, id);
- }
-
- // tell our display frame that we've changed too.
- fDrawEditor->ContentUpdated(ev, id);
-
- // Update shapes
- CalcUpdateShape(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::IsSelectionPromised
- //-----------------------------------------------------------------------------
-
- ODBoolean CSelection::IsPromisedToClipboard()
- {
- COrdListIterator ite(fDrawEditor->GetShapeList());
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (shape->IsPromisedToClipboard())
- return kODTrue;
- }
- return kODFalse;
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::ChangeSelectionColor
- //-----------------------------------------------------------------------------
-
- void CSelection::ChangeSelectionColor(Environment* ev, const CRGBColor& color)
- {
- COrdListIterator ite(fShapeList);
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- shape->SetColor(color);
- fDrawEditor->InvalidateShape(ev, shape);
- }
- if (fShapeList->Count()>0)
- SelectedContentUpdated(ev);
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::RemoveFromSelection
- // This method assumes that we are focused for drawing.
- //-----------------------------------------------------------------------------
-
- void CSelection::RemoveFromSelection(Environment* ev,
- CShape* theShape,
- ODBoolean drawHandles)
- {
- THROW_IF_NULL(theShape);
-
- if (theShape->IsSelected())
- {
-
- this->Remove(ev, theShape);
- theShape->SelectShape(ev, kODFalse);
-
- if (drawHandles)
- this->DrawShapeHandles(ev, theShape, kODFalse); // Turn Off
- }
- else
- {
- // Make sure that the shape really isn't in the selection
- #ifdef ODDebug
- ASSERT(!fShapeList->Contains(theShape), kODErrAssertionFailed);
- #endif
- }
-
- CalcUpdateShape(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::AddToSelection
- // This method assumes that we are focused for drawing.
- //-----------------------------------------------------------------------------
-
- void CSelection::AddToSelection(Environment* ev,
- CShape* theShape,
- ODBoolean drawHandles)
- {
- THROW_IF_NULL(theShape);
-
- if (!theShape->IsSelected())
- {
- theShape->SelectShape(ev, kODTrue);
-
- this->Add(ev, theShape);
- this->DrawShapeHandles(ev, theShape, drawHandles);
- }
- else
- {
- // Make sure that the shape really isn't in the selection
- #ifdef ODDebug
- ASSERT(fShapeList->Contains(theShape), kODErrAssertionFailed);
- #endif
- }
-
- CalcUpdateShape(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::ClearSelection
- //-----------------------------------------------------------------------------
-
- ODBoolean CSelection::ClearSelection(Environment* ev, ODFrame* frame)
- {
-
- // First remove publishers. This will prevent them from being updated when we call selection changed.
- // It also prevents their shapes from actually being removed from their content when they are removed
- // from the part so that if this is part 2 of a cut, a promise of a link made in part 1 can be fulfilled.
- while (fPublishLinks->Count() != 0)
- {
- CPublishLink *pLink = (CPublishLink*)fPublishLinks->RemoveFirst();
- pLink->RemoveFromPart(ev);
- }
-
- // Now, call selection changed to update any partially contained publishers, and update our display frame
- // while we still have the shapes (which point to the publishers. By passing it the doClear = kODTrue
- // it will actually remove the shapes. That's because it needs the shapes to know what links to update,
- // but can't actually update the links and the display frame until the shapes are removed.
- this->SelectedContentUpdated(ev, kODTrue);
-
- // Clip Embedded Content ( Facets ) away here in case something in the selection
- // was obscuring some embedded content.
- fDrawEditor->ClipEmbeddedFacets(ev, frame);
-
- CalcUpdateShape(ev);
-
- return kODTrue;
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::CloseSelection
- //-----------------------------------------------------------------------------
-
- void CSelection::CloseSelection(Environment* ev)
- {
- while (fShapeList->Count() != 0)
- {
- CShape *shape = (CShape*)fShapeList->First();
- this->RemoveFromSelection(ev, shape, kODTrue);
- }
-
- CalcUpdateShape(ev);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::SelectAll
- //-----------------------------------------------------------------------------
-
- void CSelection::SelectAll(Environment* ev, ODFrame* frame)
- {
- DrawHandlesForAllFacets(ev, frame, kODFalse);
-
- COrdListIterator ite(fDrawEditor->GetShapeList());
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (!shape->IsSelected())
- {
- shape->SelectShape(ev, kODTrue);
-
- this->Add(ev, shape);
- this->DrawShapeHandles(ev, shape, kODTrue);
- }
- }
-
- DrawHandlesForAllFacets(ev, frame, kODTrue);
-
- CalcUpdateShape(ev);
-
- // Make sure the palette updates correctly
- if (gGlobals->fToolPalette->GetSelectedPaletteItem()!=kSelectionTool)
- {
- ODSShort tItem = gGlobals->fToolPalette->GetSelectedPaletteItem();
-
- gGlobals->fToolPalette->SetSelectedPaletteItem(kSelectionTool);
- gGlobals->fToolPalette->InvalidateTool(ev, tItem);
- gGlobals->fToolPalette->InvalidateTool(ev, kSelectionTool);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::DrawSelectionHandles
- //-----------------------------------------------------------------------------
-
- void CSelection::DrawSelectionHandles(Environment* ev, ODFacet* facet, ODBoolean turnOn)
- {
- CFocus draw(ev, facet);
-
- COrdListIterator i(fShapeList);
- for (CShape* shape = (CShape*) i.First(); i.IsNotComplete(); shape = (CShape*) i.Next())
- {
- if ((shape->SetFrozen(turnOn))&&(turnOn))
- shape->DrawHandles();
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::InvalidateSelection
- //
- // This method should be called when some object external to the selection
- // modifies the appearance of the selection and needs it to be redrawn.
- //-----------------------------------------------------------------------------
-
- void CSelection::InvalidateSelection(Environment* ev, ODFrame* frame)
- {
- COrdListIterator ite(fDrawEditor->GetShapeList());
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- fDrawEditor->InvalidateShape(ev, shape);
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::DrawHandlesForAllFacets
- //-----------------------------------------------------------------------------
- void CSelection::DrawHandlesForAllFacets(Environment* ev, ODFrame* frame, ODBoolean turnOn)
- {
- if (fShapeList->Count() != 0)
- {
- ODFacet* facet;
- ODFrameFacetIterator* fiter = frame->CreateFacetIterator(ev);
- for ( facet = fiter->First(ev);
- fiter->IsNotComplete(ev);
- facet = fiter->Next(ev) )
- {
- DrawSelectionHandles(ev, facet, turnOn);
- }
- }
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::Activate
- // Notify embedded contents of the selection that a frame is being
- // activated/deactivated or a supend resume event has been received.
- //-----------------------------------------------------------------------------
- void CSelection::Activate(Environment* ev, ODBoolean activating, ODFrame* frame)
- {
- COrdListIterator ite(fShapeList);
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- shape->Activate(ev, activating, frame);
- }
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::DrawShapeHandles
- //
- // Draw the shapes handles in all frames
- //-----------------------------------------------------------------------------
- void CSelection::DrawShapeHandles(Environment* ev, CShape* shape, ODBoolean turnOn)
- {
- COrderedList* contentFrames = GetDrawEditor()->GetContentDisplayFrames(ev);
- THROW_IF_NULL(contentFrames);
-
- if (contentFrames->Count()>0)
- {
- COrdListIterator iter(contentFrames);
- for ( ODFrame* frame = (ODFrame*)iter.First();
- iter.IsNotComplete();
- frame = (ODFrame*)iter.Next() )
- {
- // invalidate handles
- shape->InvalidateHandles(ev, frame);
- }
- }
-
- delete contentFrames;
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::WhichHandle
- //-----------------------------------------------------------------------------
-
- CShape* CSelection::WhichHandle(Environment* ev, ODFacet* facet, const Point& mouse, short* whichHandle) const
- {
- *whichHandle = 0;
-
- if (fShapeList->Count() != 0)
- {
- COrdListIterator ite(fShapeList);
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- *whichHandle = shape->WhichHandle( mouse);
- if (*whichHandle != 0)
- return shape;
- }
- }
-
- return NULL;
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::TrackRectangle
- //-----------------------------------------------------------------------------
- ODBoolean CSelection::TrackRectangle(Environment* ev, ODEventData* event, Rect* selection)
- {
- const Pattern kAntPattern = {0xEE, 0x77, 0xBB, 0xDD, 0xEE, 0x77, 0xBB, 0xDD};
-
- // If the mouse doesn't move, return
- if (!::WaitMouseMoved(event->where))
- return kODFalse;
-
- // Remember the pen state
- ::PenState savePen;
- ::GetPenState(&savePen);
-
- // Ant Pattern
- ::PenMode(patXor);
- ::PenPat(&kAntPattern);
-
- // Get the anchor point
- Point anchorPoint = event->where;
- ::GlobalToLocal(&anchorPoint);
-
- // Initialize the current and previous points
- Point currentLoc = anchorPoint;
-
- // Track the rectangle
- ODBoolean mouseMoved = kODTrue;
- do
- {
- if (mouseMoved)
- {
- ::GetMouse(¤tLoc);
- ::Pt2Rect(anchorPoint, currentLoc, selection);
- ::FrameRect(selection);
- }
-
- mouseMoved = ::WaitMouseMoved(currentLoc);
-
- if (mouseMoved)
- ::FrameRect(selection);
- }
- while (::WaitMouseUp());
-
- // If WaitMouseMoved returned false before the mouseup, then turn off
- // the selection rectangle.
- if (!mouseMoved)
- FrameRect(selection);
-
- ::Pt2Rect(anchorPoint, currentLoc, selection);
-
- // Restore the pen state
- ::SetPenState(&savePen);
-
- return kODTrue;
-
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::SelectWithShape
- //-----------------------------------------------------------------------------
- void CSelection::SelectWithShape(Environment* ev,
- ODFacet* facet,
- ODEventData* event,
- CShape* shape)
- {
- // If the shift key is down, extend selection
- if (event->modifiers & shiftKey)
- {
- if (shape->IsSelected())
- this->RemoveFromSelection(ev, shape, TRUE);
- else
- this->AddToSelection(ev, shape, TRUE);
- }
- else if (!shape->IsSelected())
- {
- this->CloseSelection(ev);
- this->AddToSelection(ev, shape, TRUE);
- }
-
- // If the mouse doesn't move, don't bother dragging
- if (!WaitMouseMoved(event->where))
- return;
-
- // if a shape is selected start dragging
- if (shape->IsSelected())
- {
- CDragShapeCommand* dragCommand =
- new CDragShapeCommand(fDrawEditor, facet, this,
- event, kODTrue, kODTrue);
-
- if (dragCommand)
- {
- fDrawEditor->ExecuteCommand(ev, dragCommand);
- }
- }
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::SelectWithRectangle
- //-----------------------------------------------------------------------------
- void CSelection::SelectWithRectangle(Environment* ev, ODFacet* facet, ODEventData* event)
- {
- // Need to be focused for drawing for visual feedback
- CFocus draw(ev, facet);
-
- ODBoolean isShift = event->modifiers & shiftKey;
-
- Rect selectRect;
-
- if (this->TrackRectangle(ev, event, &selectRect))
- {
-
- COrdListIterator ite(fDrawEditor->GetShapeList());
- for (CShape *shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- if (shape->ShapeInRectangle(selectRect))
- {
- if (shape->IsSelected())
- {
- if (isShift)
- {
- Remove(ev, shape);
- shape->SelectShape(ev, kODFalse);
- DrawShapeHandles(ev, shape, kODFalse); // Turn Off
- }
- }
- else
- {
- Add(ev, shape);
- shape->SelectShape(ev, kODTrue);
- DrawShapeHandles(ev, shape, kODTrue); // Turn on
- }
- }
- else if (shape->IsSelected() && !isShift)
- {
- shape->SelectShape(ev, kODFalse);
- Remove(ev, shape);
- DrawShapeHandles(ev, shape, kODFalse); // Turn Off
- }
- }
- CalcUpdateShape(ev);
- }
- else
- {
- CloseSelection(ev);
- }
-
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::CreateDragShape
- //-----------------------------------------------------------------------------
- ODShape* CSelection::CreateDragShape(Environment* ev, ODFacet* facet, ODFrame* frame)
- {
- ODShape* dragShape = facet->CreateShape(ev);
-
- ODRect tRect(fSelectionRectangle);
-
- dragShape->SetRectangle(ev, &tRect);
-
- // Outline the shape in preparation for drag feedback
- ODShape* tShape = dragShape->Copy(ev);
- tShape->Outset(ev, ff(-1));
- dragShape->Subtract(ev, tShape);
-
- // Release ref counted geometry
- ODReleaseObject(ev, tShape);
-
- return dragShape;
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::CalcUpdateShape
- //-----------------------------------------------------------------------------
- void CSelection::CalcUpdateShape(Environment* ev)
- {
- fSelectionRectangle = gGlobals->fZeroRect;
-
- TRY
- // Find a factory for temp shape creation
- ODFrame* tFrame = this->GetDrawEditor()->GetANYFrame(ev);
- THROW_IF_NULL(tFrame);
-
- if (fUpdateShape == NULL)
- fUpdateShape = tFrame->CreateShape(ev);
-
- if (fShapeList->Count() == 0)
- return;
-
- TempODShape aqTempShape = tFrame->CreateShape(ev);
- Rect tempRect;
-
- ODBoolean first = kODTrue;
-
- COrdListIterator iter(fShapeList);
- for ( CShape* shape = (CShape*)iter.First();
- iter.IsNotComplete();
- shape = (CShape*)iter.Next() )
- {
- shape->GetDragRect(&tempRect);
- shape->GetUpdateShape(ev, aqTempShape);
- if (first)
- {
- fSelectionRectangle = tempRect;
- fUpdateShape->CopyFrom(ev, aqTempShape);
- }
- else
- {
- UnionRect(&fSelectionRectangle, &tempRect, &fSelectionRectangle);
- fUpdateShape->Union(ev, aqTempShape);
- }
-
- first = kODFalse;
- }
-
- CATCH_ALL
- #ifdef ODDebug
- DebugStr("\p Exception thrown creating facets!");
- #endif
- ENDTRY
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::TrackResize
- //-----------------------------------------------------------------------------
- void CSelection::TrackResize(Environment* ev,
- ODFacet* facet,
- ODEventData* event,
- ODSShort whichHandle,
- CShape* shape,
- Point* result)
- {
-
- const Pattern kAntPattern = {0xEE, 0x77, 0xBB, 0xDD, 0xEE, 0x77, 0xBB, 0xDD};
-
- // Need to be focused for drawing for visual feedback
- CFocus draw(ev, facet);
-
- // Remember the pen state
- ::PenState savePen;
- ::GetPenState(&savePen);
-
- // Ant Pattern
- ::PenMode(patXor);
- ::PenPat(&kAntPattern);
-
- // Track the rectangle
- do
- {
- ::GetMouse(result);
-
- // shape->GetResizeRect(whichHandle, currentLoc, result);
- shape->ResizeFeedback(facet, whichHandle, *result, kODTrue);
-
- if (::WaitMouseMoved(*result))
- {
- shape->ResizeFeedback(facet, whichHandle, *result, kODFalse);
- }
-
- }
- while (::WaitMouseUp());
-
- shape->ResizeFeedback(facet, whichHandle, *result, kODFalse);
-
- // Restore the pen state
- SetPenState(&savePen);
- }
-
- //-----------------------------------------------------------------------------
- // CSelection::Resize
- //-----------------------------------------------------------------------------
- void CSelection::Resize(Environment* ev,
- CShape* anchor,
- ODFacet* containingFacet,
- short whichHandle,
- ODEventData* event)
- {
- Point result;
- Rect baseRect, resizeRect;
- ODBoolean validRect;
-
- // If the mouse doesn't move, return
- if (!WaitMouseMoved(event->where))
- return;
-
- // Track the resize
- TrackResize(ev, containingFacet, event, whichHandle, anchor, &result);
-
- // Get & Validate the resize rectangle
- anchor->GetResizeRect(whichHandle, result, &baseRect, &resizeRect );
- validRect = !::EmptyRect(&resizeRect);
-
- if (validRect == kODTrue)
- {
- // Create & Execute resize command
- CResizeSelectionCommand* command = new
- CResizeSelectionCommand(fDrawEditor, containingFacet, this, baseRect, resizeRect);
- THROW_IF_NULL(command);
-
- fDrawEditor->ExecuteCommand(ev, command);
-
- }
- }
-
-
-
- //-----------------------------------------------------------------------------
- // CSelection::ResizeSelection
- //-----------------------------------------------------------------------------
- void CSelection::ResizeSelection(Environment* ev,
- ODFrame* containingFrame,
- Rect baseRect,
- Rect resizeRect)
- {
- ODShape* tUnionShape = fUpdateShape->Copy(ev);
-
- COrdListIterator ite(fShapeList);
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- shape->Resize(ev, baseRect, resizeRect);
- }
-
- CalcUpdateShape(ev);
-
- tUnionShape->Union(ev, fUpdateShape);
-
- // Reset clipping
- fDrawEditor->ClipEmbeddedFacets(ev, containingFrame);
-
- // Invalidate move to / from area
- containingFrame->Invalidate(ev, tUnionShape, kODNULL);
-
- // Release ref counted geometry
- ODReleaseObject(ev, tUnionShape);
- }
-
-
- //-----------------------------------------------------------------------------
- // CSelection::OffsetSelection
- //-----------------------------------------------------------------------------
- void CSelection::OffsetSelection(Environment* ev,
- ODFrame* containingFrame,
- ODCoordinate hOffset,
- ODCoordinate vOffset)
- {
- ODShape* tUnionShape = fUpdateShape->Copy(ev);
-
- COrdListIterator ite(fShapeList);
- for (CShape* shape = (CShape*)ite.First(); ite.IsNotComplete(); shape = (CShape*)ite.Next())
- {
- shape->OffsetShape(ev, hOffset, vOffset);
- }
-
- CalcUpdateShape(ev);
-
- // Create a union of the old and the new shapes
- tUnionShape->Union(ev, fUpdateShape);
-
- // If there is an active border shape then it was probably dragged as well
- fDrawEditor->InvalidateActiveBorder(ev, containingFrame);
-
- // Reset clipping
- fDrawEditor->ClipEmbeddedFacets(ev, containingFrame);
-
- // Invalidate move to / from area
- containingFrame->Invalidate(ev, tUnionShape, kODNULL);
-
- // Release ref counted geometry
- ODReleaseObject(ev, tUnionShape);
- }
-
- #pragma segment DrawEditor
- CPublishLink *CSelection::FindPublisher()
- {
- CPublishLink *link = NULL;
-
- if (fPublishLinks->Count() > 0)
- {
-
- COrdListIterator linkIte(fPublishLinks);
- for (link = (CPublishLink*)linkIte.First(); linkIte.IsNotComplete(); link = (CPublishLink*)linkIte.Next())
- {
- // set theory: If the link is a subset of the selection, and has the same number of shapes
- // as the selection, then it must be the selection
-
- if (link->Count() == fShapeList->Count())
- break;
- else
- link = NULL;
- }
- }
-
- return link;
- }
-
- #pragma segment DrawEditor
- void CSelection::AddShapeToPart(Environment* ev, CShape* shape)//Override
- {
- // Add it to editor's content
- fDrawEditor->AddShape(ev, shape);
-
- }
-
- #pragma segment Main
- void CSelection::AddPublishLink(CPublishLink* link)
- {
- fPublishLinks->AddLast(link);
- }
-
-
- #pragma segment Main
- void CSelection::RemovePublishLink(CPublishLink* link)
- {
- fPublishLinks->Remove(link);
- }
-
-
- #pragma segment Main
- void CSelection::AddSubscribeLink(CSubscribeLink* link)
- {
- fSubscribeLinks->AddLast(link);
- --fPartialSubscribeCount;
- }
-
-
- #pragma segment Main
- void CSelection::RemoveSubscribeLink(CSubscribeLink* link)
- {
- fSubscribeLinks->Remove(link);
- ++fPartialSubscribeCount;
- }
-
-
- #pragma segment Main
- void CSelection::IncrementPartialSubscribeCount(ODUShort increment)
- {
- fPartialSubscribeCount += increment;
- }
-
-
- #pragma segment Main
- ODBoolean CSelection::CanMoveSelectedContent(CSubscribeLink*& link)
- {
- // This test returns false if there are any partially selected
- // subscribers. If there is just one partially selected subscriber
- // then that subscriber is returned in the link parameter.
-
- if (fPartialSubscribeCount == 1)
- {
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- link = shape->GetSubscribeLink();
- if (link)
- break;
- }
-
- }
-
- return this->CanMoveSelectedContent();
- }
-
-
- #pragma segment Main
- ODBoolean CSelection::CanEditSelectedContent()
- {
- return (!fPartialSubscribeCount && !fSubscribeLinks->Count());
- }
-
- ODBoolean CSelection::CanPublish()
- {
- ODBoolean result = (fPartialSubscribeCount == 0) &&
- !fDrawEditor->IsReadOnly() &&
- (fDrawEditor->GetLinkStatus() != kODInLinkDestination);
-
- if (result && fSubscribeLinks->Count() == 1)
- {
- CSubscribeLink* link = (CSubscribeLink*)fSubscribeLinks->First();
- result = fShapeList->Count() > link->Count();
- }
-
- return result;
-
- }
-
- #pragma segment Main
- ODBoolean CSelection::CanMoveSelectedContent()
- {
- return (fPartialSubscribeCount == 0);
- }
-
-
- #pragma segment Main
- ODBoolean CSelection::CanEditSelectedContent(CSubscribeLink*& link)
- {
- ODULong count = fPartialSubscribeCount + fSubscribeLinks->Count();
-
- if (count == 1)
- {
- link = (CSubscribeLink*)fSubscribeLinks->First();
-
- if (!link)
- {
- COrdListIterator iter(fShapeList);
- for (CShape* shape = (CShape*)iter.First(); iter.IsNotComplete(); shape = (CShape*)iter.Next())
- {
- link = shape->GetSubscribeLink();
- if (link)
- break;
- }
- }
- }
-
- return (count == 0);
- }
-
-
- #pragma segment Main
- ODBoolean CSelection::IsOneLink()
- {
- // This is called to determine if there is an unambiguous link that can be accessed using
- // a link info dialog.
-
- // $$$$$ we're going to make it easy on ourselves by ignoring any partially selected publish links.
- // this just means that to use link info, the user must select an entire publish link.
- // the alternative, is to walk each shape and each shape's list of publishers to insure that there
- // is only one publisher represented. A more efficient approach would be to maintain an
- // fPartialPublishCount as we do now an fPartialSubscribeCount.
-
- ODULong count = fPartialSubscribeCount + fSubscribeLinks->Count() + fPublishLinks->Count();
-
- return (count == 1);
-
- }
-
-
-
-